<?php namespace App\Services;

use App\AgentOpenid;
use App\Exceptions\NotFoundException;
use App\Exceptions\SecurityException;
use Illuminate\Http\Request;
use App\User;
use Auth;
use App\Exceptions\SignInException;
use App\Exceptions\SignUpException;
use App\Exceptions\BindUserException;
use Blocktrail\CryptoJSAES\CryptoJSAES;
use Carbon\Carbon;
use Illuminate\Support\Str;
use Cookie;

class UserManager
{
    public static function isLogin(Request $request = null)
    {
        if (!isset($_COOKIE['user_token'])) {
            if (is_null($request)) {
                return false;
            } else {
                $token = !is_null($request->header('user_token')) ? $request->header('user_token') : $request->get('user_token');
                if (!is_null($token)) {

                    $openid = false;
                    try {
                        $openid = CryptoJSAES::decrypt(str_replace(" ", "+", $token), env("AES_KEY"));
                        $openid = str_replace('wx_openid@' , "" , $openid);
                    } catch (\Exception $e) {
                        return false;
                    }

                    if (!$openid)
                        return false;

                    $thatUser = User::whereOpenid($openid)->first();
                    if (!$thatUser){
                        $thatUser = User::whereUserKey($openid)->first();
                        if(!$thatUser){
                            return false;
                        }
                    }

                    return $thatUser;
                } else {
                    return false;
                }
            }
        } else {
            $token = Cookie::get('user_token');

            //$front等于0，就会一直使用前端传来的user_token,$front不等于0会优先使用cookie中的user_token，若cookie中没有，才会使用前端传来的user_token
            if (!$token || is_null($token) || $token == ''){
                $token = !is_null($request->header('user_token')) ? $request->header('user_token') : $request->get('user_token');
            }

            if(!is_null($token)){
                $openid = false;
                try {
                    $openid = CryptoJSAES::decrypt(str_replace(" ", "+", $token), env("AES_KEY"));
                    $openid = str_replace('wx_openid@' , "" , $openid);
                } catch (\Exception $e) {
                    return false;
                }

                if (!$openid)
                    return false;

                $thatUser = User::whereOpenid($openid)->first();
                if (!$thatUser){
                    $thatUser = User::whereUserKey($openid)->first();
                    if(!$thatUser){
                        return false;
                    }
                }

                return $thatUser;
            }else{
                return false;
            }
        }
    }

    /**
     * 检查用户名是否已经存在或被使用
     * @param $username
     * @return bool
     */
    public static function isUsernameExists($username){
        if(User::whereUsername($username)->exists())
             return true;
        return false;
    }

    /**
     * 检查email是否已经存在或被使用
     * @param $email
     * @return bool
     */
    public static function isEmailExists($email){
        if(User::whereEmail($email)->exists())
            return true;
        return false;
    }

    /**
     * 检查手机号码是否已经存在或已经被使用
     * @param $phone
     * @return bool
     */
    public static function isPhoneExists($phone){
        if(User::wherePhone($phone)->exists())
            return true;
        return false;
    }

    /**
     * 用户注册对应方法
     * @param $username
     * @param $email
     * @param $phone
     * @param $password
     * @return User
     * @throws SignUpException
     */
    public static function signUp($username, $email, $phone, $password,$role){
        if(!is_null($username) && self::isUsernameExists($username))
            throw new SignUpException(SignUpException::UsernameExists,['username' => $username]);

        if(!is_null($email) && self::isEmailExists($email))
            throw new SignUpException(SignUpException::EmailExists,['email' => $email]);

        if(!is_null($phone) && self::isPhoneExists($phone))
            throw new SignUpException(SignUpException::PhoneExists,['phone' => $phone]);

        $user              = new User();
        $user->username    = !is_null($username) ? $username:null;
        $user->email       = Tools::isEmail($email) ? $email:null;
        $user->phone       = Tools::isPhone($phone) ? $phone:null;
        $user->password    = bcrypt($password);
        $user->reg_ip      = \Input::ip();
        $user->reg_time    = Carbon::now();
        $user->login_ip    = NULL;
        $user->login_time  = date('Y-m-d',time());
        $user->login_count = 0;
        $user->role        = !is_null($role) ? $role:0;
        $user->save();

        return $user;
    }

    /**
     * 通过用户名来登录
     * @param $username
     * @param $password
     * @param bool $remeber
     * @return User|null
     * @throws SignInException
     */
    public static function signInByUsername($username, $password, $remember = false){
        if(!self::isUsernameExists($username))
            throw new SignInException(SignInException::UserNameNotExists);

        if(Auth::attempt(['username' => $username, 'password' => $password],$remember)){
            return Auth::user();
        }

        throw new SignInException(SignInException::PasswordNotMatch);
    }

    /**
     * 通过email登录
     * @param $email
     * @param $password
     * @param bool $remember
     * @return User|null
     * @throws SignInException
     */
    public static function signInByEmail($email, $password, $remember=false){
        if(!self::isEmailExists($email))
            throw new SignInException(SignInException::EmailNotExists);

        if(Auth::attempt(['email' => $email, 'password' => $password],$remember)){
            return Auth::user();
        }

        throw new SignInException(SignInException::PasswordNotMatch);
    }

    /**
     * 通过 电话号码进行登录
     * @param $phone
     * @param $password
     * @param bool $remember
     * @return User|null
     * @throws SignInException
     */
    public static function signInByPhone($phone, $password ,$remember=false)
    {
        if(!self::isPhoneExists($phone))
            throw new SignInException(SignInException::PhoneNotExists);

        if(Auth::attempt(['phone' => $phone , 'password' => $password] , $remember)){
            return Auth::user();
        }
        throw new SignInException(SignInException::PasswordNotMatch);

    }

    public static function setRelationShip(User $userModel){
        $openid = $userModel->openid;

        /** @var AgentOpenid $thatAgentOpenid */
        $thatAgentOpenid = AgentOpenid::whereOpenId($openid)->first();

        if(!$thatAgentOpenid)
            return false;

        if(!$thatAgentOpenid->agent->isAgent())
            return false;


        if(count($userModel->followAgent) == 0)
            $userModel->followAgent()->attach($thatAgentOpenid->agent_id);

        return $thatAgentOpenid;
    }

//    /**
//     * 通过 邮箱重置密码
//     * @param $email
//     * @param $newPasswd
//     * @return false|User
//     */
//    public static function resetPasswdByEmail($email, $newPasswd){
//        /*实例化模型*/
//        $user       = new User();
//
//        /*查询用户*/
//        $result=$user->whereEmail($email)->first();
//
//        /*如果用户未注册则抛出未注册错误*/
//        if(!$result)
//            throw new SignInException(SignInException::EmailNotExists);
//
//        /*数据更新赋值*/
//        $result->password= bcrypt($newPasswd);
//
//        /*执行更新 失败抛出数据保存失败错误*/
//        if(!$result->save())
//            return false;
//        /*正常返回*/
//        return $result;
//    }

//    /**
//     * 绑定手机号到当前登录用户
//     * @param $phone
//     * @return User
//     * @throws BindUserException
//     */
//    public static function bindPhoneToThisUser($phone){
//
//        /*用户认证失败则抛出认证失败错误*/
//        if(! Auth::check())
//            throw new BindUserException(BindUserException::UserAuthError);
//
//        /*获取当前登录用户实例*/
//        $user=Auth::user();
//
//        /*赋值*/
//        $user->phone=$phone;
//
//        /*保存更改*/
//        if($user->save())
//            return $user;
//
//        /*失败则抛出绑定失败错误*/
//        throw new BindUserException(BindUserException::SaveError);
//
//    }
}